home *** CD-ROM | disk | FTP | other *** search
- .286
- ;================================================
- ; Multiplies REAL10's dst, src
- ;
- ;------------------------------------------------
- cseg segment word public 'code'
- assume cs:cseg,ss:cseg
- assume ds:cseg,es:cseg
-
- include math.inc
-
- ftmul proc near dst:NPR10, src:NPR10
- local t:REAL10, dcopy[8]:WORD, result[8]:WORD
-
- pusha
- mov si, src
- mov di, dst
-
- invoke ftzero, si ; if src = 0.0
- .IF ax == TRUE ;
- invoke clrx, di, 5 ; dst = 0.0
- jmp exit ;
- .ENDIF ;
-
- invoke ftzero, di ; if dst = 0.0
- .IF ax == TRUE ;
- jmp exit ; dst unchanged
- .ENDIF ;
-
- invoke movx, addr t, si, 5 ; don't violate src
- lea si, t ;
-
- invoke ftcomp, di, si ;
- .IF ax == 1 ; if dst > src
- invoke ftswap, di, si ;
- .ENDIF
- ;------------------------------------------------
- ; get resultant exponent and sign
- ;------------------------------------------------
- mov ax, word ptr [di]+8 ;
- mov bl, ah ;
- and bl, 80h ; BL = dst sign
- and ax, 7fffh ;
- sub ax, 3fffh ;
-
- mov dx, word ptr [si]+8 ;
- mov bh, dh ;
- and bh, 80h ; BH = src sign
- and dx, 7fffh ;
- sub dx, 3fffh ;
-
- add ax, dx ; add true binary exponents
- add ax, 3fffh ; add bias
-
- .IF ((bx == 8000h) || (bx == 80h)); if -dst, +src OR +dst, -src
- or ax, 8000h ; result is -ve
- .ENDIF ;
-
- mov word ptr [di]+8, ax ;
- ;------------------------------------------------
- ; note: 64-bit x 64-bit = 128-bit result
- ;------------------------------------------------
- invoke clrx, addr dcopy, 8 ; clear 8-word dcopy
- invoke movx, addr dcopy, di, 4 ; load lower 4 words
- lea di, dcopy ; ss::di addresses dcopy
-
- invoke clrx, addr result, 8 ; clear 8-word result
- ;------------------------------------------------
- ; shift and add multiplication
- ;------------------------------------------------
- xor dx, dx ; overflow = 0
- mov cx, 64 ; 64 bits
-
- .WHILE (cx)
- invoke cmpxz, si, 4
- .BREAK .IF (ax == TRUE) ;
-
- invoke lshx, si, 4 ; left shift t64
- .IF ax == 1 ; if msb == 1
- invoke addx, addr result, di, 8 ; add result, dcopy
- or dx, ax ; catch overflow
- .ENDIF
- invoke lshx, addr result, 8 ; left shift result
- dec cx ; continue
- .ENDW
- ;------------------------------------------------
- ; adjust for overflow
- ;------------------------------------------------
- mov di, dst ; address dst
- lea si, result ; address result
-
- .IF (dx) ; if overflow
- invoke rshx, si, 8 ;
- or word ptr [si]+14, 8000h
- inc word ptr [di]+8 ;
- .ENDIF ;
- ;------------------------------------------------
- ; normalise 128 bit result
- ;------------------------------------------------
- .WHILE (1) ;
- mov ax, word ptr [si]+14 ;
- .BREAK .IF (ax & 8000h) ;
- invoke lshx, si, 8 ;
- .ENDW ;
-
- add si, 8 ; address upper 4 words
- invoke cmpx, di, si, 4 ;
- .IF ax == 1 ; if result64 < dst64
- inc word ptr [di]+8 ; exp++
- .ENDIF ;
- invoke movx, di, si, 4 ; dst64 <--- result
- exit:
- popa
- ret
- ftmul endp
-
- cseg ends
- end